/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.javahispano.javacup.tacticas.tacticas_aceptadas.tacticaMonsters;


import org.javahispano.javacup.modelo.engine.SituacionPartido;
import org.javahispano.javacup.modelo.util.Posicion;
import org.javahispano.javacup.modelo.util.Constantes;
import org.javahispano.javacup.modelo.TacticaDetalle;
import org.javahispano.javacup.modelo.JugadorDetalle;
import org.javahispano.javacup.modelo.Tactica;
import org.javahispano.javacup.modelo.comando.Comando;
import org.javahispano.javacup.modelo.comando.ComandoIrA;
import org.javahispano.javacup.modelo.comando.ComandoGolpearBalon;
import org.javahispano.javacup.render.EstiloUniforme;
import java.awt.Color;
import java.util.LinkedList;
import org.javahispano.javacup.modelo.*;
import java.util.List;
import java.util.Random;
public class Monsters implements Tactica {
SituacionPartido spAct;
Simulador sim=new Simulador();
LinkedList<Comando> comandos = new LinkedList<Comando>();
    Posicion alineacion1[]=new Posicion[]{
        //(-30,30)(-50..50)
        new Posicion(0,-49),
        new Posicion(6,-46),
        new Posicion(-6,-46),
        new Posicion(-12,-25),
        new Posicion(12,-25),
        new Posicion(0,0),

        new Posicion(-18,6),
        new Posicion(18,6),
        new Posicion(5,21),

        new Posicion(-5,21),
        new Posicion(0.0,42.047511312217196)
        
    };

    Posicion alineacion2[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(27.251908396946565,-27.94776119402985),
        new Posicion(-29.84732824427481,-26.902985074626866),
        new Posicion(8.564885496183205,-7.574626865671642),
        new Posicion(-10.641221374045802,-7.052238805970149),
        new Posicion(27.251908396946565,4.440298507462686),
        new Posicion(-29.32824427480916,3.3955223880597014),
        new Posicion(-0.2595419847328244,19.067164179104477),
        new Posicion(-0.2595419847328244,35.78358208955224)
    };

    Posicion alineacion3[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(26.732824427480914,-20.111940298507463),
        new Posicion(-29.32824427480916,-21.67910447761194),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(-18.946564885496183,-0.26119402985074625),
        new Posicion(18.946564885496183,-0.26119402985074625),
        new Posicion(-19.46564885496183,35.78358208955224),
        new Posicion(-0.2595419847328244,19.067164179104477),
        new Posicion(18.946564885496183,35.26119402985075)
    };

    Posicion alineacion4[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-31.082089552238806),
        new Posicion(11.16030534351145,-31.6044776119403),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(11.16030534351145,-1.3059701492537314),
        new Posicion(-10.641221374045802,-0.7835820895522387),
        new Posicion(-27.251908396946565,31.6044776119403),
        new Posicion(-10.641221374045802,30.559701492537314),
        new Posicion(9.603053435114505,28.992537313432837),
        new Posicion(25.69465648854962,28.992537313432837)
    };

    Posicion alineacion5[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(5.969465648854961,-5.485074626865671),
        new Posicion(0.2595419847328244,-0.26119402985074625),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };

    Posicion alineacion6[]=new Posicion[]{
        new Posicion(0.2595419847328244,-50.41044776119403),
        new Posicion(-11.16030534351145,-35.78358208955224),
        new Posicion(12.717557251908397,-35.26119402985075),
        new Posicion(28.290076335877863,-28.470149253731343),
        new Posicion(-28.290076335877863,-28.470149253731343),
        new Posicion(14.793893129770993,-18.544776119402986),
        new Posicion(-17.389312977099234,-19.58955223880597),
        new Posicion(-23.618320610687025,-0.7835820895522387),
        new Posicion(6.4885496183206115,-6.529850746268657),
        new Posicion(-6.4885496183206115,-6.529850746268657),
        new Posicion(22.580152671755727,-1.3059701492537314)
    };

    private void aPorPelota(int jugador) {
       
        Posicion pos=spAct.misJugadores()[jugador];
        double alturaControl=Constantes.ALTURA_CONTROL_BALON;
        if(jugador==0){alturaControl=Constantes.ALTO_ARCO;}
        double velocidad=0.25+spAct.detalleMisJugadores()[jugador].getVelocidad()*0.25;
        for(int i=0;i<500;i++){
            double[] posBalon3c=spAct.getTrayectoria(i);
            if(posBalon3c[2]>alturaControl){continue;}
            Posicion posBalon=new Posicion(posBalon3c[0],posBalon3c[1]);
            double dist=pos.distancia(posBalon);
            if(dist-Constantes.DISTANCIA_CONTROL_BALON<=velocidad*i){
                comandos.add(new ComandoIrA(jugador, posBalon));
                break;
            }
        }
    }

    class TacticaDetalleImpl implements TacticaDetalle {

        public String getNombre() {
            return "Monsters";
        }

        public String getPais() {
            return "Alemania";
        }

        public String getEntrenador() {
            return "Maicky Materson";
        }

        public Color getColorCamiseta() {
            return new Color(51, 255, 0);
        }

        public Color getColorPantalon() {
            return new Color(255, 255, 255);
        }

        public Color getColorFranja() {
            return new Color(255, 51, 51);
        }

        public Color getColorCalcetas() {
            return new Color(255, 0, 0);
        }

        public Color getColorPortero() {
            return new Color(150, 85, 35        );
        }

        public EstiloUniforme getEstilo() {
            return EstiloUniforme.SIN_ESTILO;
        }

        public Color getColorCamiseta2() {
            return new Color(68, 79, 16);
        }

        public Color getColorPantalon2() {
            return new Color(23, 52, 180);
        }

        public Color getColorFranja2() {
            return new Color(109, 53, 160);
        }

        public Color getColorCalcetas2() {
            return new Color(203, 107, 206);
        }

        public Color getColorPortero2() {
            return new Color(13, 111, 103        );
        }

        public EstiloUniforme getEstilo2() {
            return EstiloUniforme.FRANJA_VERTICAL;
        }

        class JugadorImpl implements JugadorDetalle {

            String nombre;
            int numero;
            Color piel, pelo;
            double velocidad, remate, presicion;
            boolean portero;
            Posicion posicion;

            public JugadorImpl(String nombre, int numero, Color piel, Color pelo,
                    double velocidad, double remate, double presicion, boolean portero) {
                this.nombre=nombre;
                this.numero=numero;
                this.piel=piel;
                this.pelo=pelo;
                this.velocidad=velocidad;
                this.remate=remate;
                this.presicion=presicion;
                this.portero=portero;
            }

            public String getNombre() {
                return nombre;
            }

            public Color getColorPiel() {
                return piel;
            }

            public Color getColorPelo() {
                return pelo;
            }

            public int getNumero() {
                return numero;
            }

            public boolean esPortero() {
                return portero;
            }

            public double getVelocidad() {
                return velocidad;
            }

            public double getRemate() {
                return remate;
            }

            public double getPresicion() {
                return presicion;
            }

        }

        public JugadorDetalle[] getJugadores() {
            return new JugadorDetalle[]{
                new JugadorImpl("Mark Lenders", 1, new Color(51,0,0), new Color(255,255,255),1.0d,1.0d,1.0d, true),
                new JugadorImpl("Michael Jordan", 2, new Color(51,51,51), new Color(255,255,255),1.0d,1.0d,0.5d, false),
                new JugadorImpl("Hubert Farnsworth", 3, new Color(255,204,204), new Color(255,255,255),1.0d,1.0d,0.5d, false),
                new JugadorImpl("Roberto", 4, new Color(255,102,51), new Color(255,255,255),1.0d,1.0d,0.5d, false),
                new JugadorImpl("Zoidberg", 5, new Color(255,102,102),new Color(255,255,255),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Trokero", 6, new Color(255,204,204), new Color(255,255,255),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Txori", 7, new Color(255,0,0), new Color(255,255,255),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Jonan", 8, new Color(255,0,0), new Color(255,255,255),1.0d,0.5d,0.5d, false),
                new JugadorImpl("Josepo", 9, new Color(255,0,0), new Color(255,255,255),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Harringui", 10, new Color(255,0,0), new Color(255,255,255),1.0d,1.0d,1.0d, false),
                new JugadorImpl("Jonhy Temeto", 11, new Color(255,0,0), new Color(255,255,255),1.0d,1.0d,1.0d, false)
            };
        }
    }

    TacticaDetalle detalle=new TacticaDetalleImpl();
    public TacticaDetalle getDetalle() {
        return detalle;
    }

    public Posicion[] getPosicionSaca(SituacionPartido sp) {
    return alineacion5;
    }

    public Posicion[] getPosicionRecive(SituacionPartido sp) {
    return alineacion6;
    }

    public void posicionarJugadores(){
         Posicion[] jugadores = spAct.misJugadores();
        for (int i = 0; i < jugadores.length; i++) {
            comandos.add(new ComandoIrA(i, Alineacion.obtPos(i, spAct.balon())));
        }

    }
    public void irAporPelota(){
         if (!spAct.sacaRival()) {
            int[] recuperadores = spAct.getRecuperacionBalon();
            if (recuperadores.length > 1) {
                double[] posRecuperacion = spAct.getTrayectoria(recuperadores[0]);
                for (int i = 1; i < recuperadores.length; i++) {
                    Posicion posRecu=new Posicion(posRecuperacion[0], posRecuperacion[1]);
                    if(recuperadores[i]==0&&posRecu.getY()<-38&&Math.abs(posRecu.getX())<10){
                    comandos.add(new ComandoIrA(recuperadores[i],posRecu));}
                    if(recuperadores[i]==10&&(recuperadores.length==1||(posRecu.getY()>32))){
                    comandos.add(new ComandoIrA(recuperadores[i],posRecu));}
                    if(recuperadores[i]>0&&recuperadores[i]<10){
                    comandos.add(new ComandoIrA(recuperadores[i],posRecu));}
                 }
                 Posicion posRecu=new Posicion(posRecuperacion[0], posRecuperacion[1]);
                if(posRecu.getY()<-38&&Math.abs(posRecu.getX())<15){

                        aPorPelota(1);
                        aPorPelota(2);
                }
            }


        }
    }

    public List<Comando> ejecutar(SituacionPartido sp) {

       
        spAct=sp;
        comandos.clear();
        posicionarJugadores();
        irAporPelota();

        if(spAct.puedenRematar().length>0){
             for (int i : sp.puedenRematar()) {
                 if(i<3){//despejar
                     //if(i==0){System.out.println("porteroo"+spAct.iteracion());}
                     comandos.add(new ComandoGolpearBalon(i, Constantes.centroArcoSup, 1, 45));
                 }else if(sp.balon().distancia(Constantes.centroArcoSup)<35){//tiro desde cerca
                     double tiro[]=sim.calcularTiroCercano(spAct.alturaBalon(),
                             sp.balon().distancia(Constantes.centroArcoSup),
                             spAct.detalleMisJugadores()[i].getRemate()*1.2+1.2);
                     comandos.add(new ComandoGolpearBalon(i, Constantes.centroArcoSup, 1, tiro[0]));
                 }else{
                     double[] distMaxPosible=sim.distanciaHastaControlBalon2(spAct.alturaBalon(),
                     spAct.detalleMisJugadores()[i].getRemate()*1.2+1.2, 45, true);
                      boolean tiroLejano=false;
                     if(sp.balon().distancia(Constantes.centroArcoSup)<distMaxPosible[0]){
                         //puedo tirar de lejos
                         tiroLejano=true;
                         if(tiroLejano){
                                double[] tiro= sim.calcularTiroAlto(sp.alturaBalon(),
                                 sp.balon().distancia(Constantes.centroArcoSup),
                            1.2+1.2*sp.detalleMisJugadores()[i].getRemate());
                                comandos.add(new ComandoGolpearBalon(i, Constantes.centroArcoSup,
                                        tiro[0], tiro[1]));

                         }


                     }
                     if(!tiroLejano){
                        //buscamos el pase
                         int jug=jugAdelantadoPosible(i);
                         boolean pase2=false;
                        if(jug!=-1){

                            float factor=1;
                            if(spAct.saco()&&Math.abs(spAct.balon().getX())>30){
                                factor=(float) 0.4;
                            }
                             double[] pase=sim.calcularPaseAire((1.2+1.2*spAct.detalleMisJugadores()[i].getRemate())*factor,
                            spAct.misJugadores()[jug].distancia(sp.balon()), sp.alturaBalon());
                    if(pase[0]!=-1){
                        pase2=true;
                        //System.out.println("pase!");
                        //System.out.println("pase Bueno :) "+spAct.iteracion());
                        comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[jug], pase[0], pase[1]));
                    }else{
                        //System.out.println("paseSecon!");
                        //System.out.println("pase maloo! "+spAct.iteracion());
                         comandos.add(new ComandoGolpearBalon(i, sp.misJugadores()[jug], 1,45 ));
                         pase2=true;
                    }
                }else{
                     
                }
                if(!pase2){
                    //System.out.println("Tiro!!! defecto "+i);
                   // System.out.println("aleatorio "+spAct.iteracion());
                    comandos.add(new ComandoGolpearBalon(i, Constantes.centroArcoSup, 1, 20));

                }
                         
                     }

                 }

             }
        }
       
        
        
        
        return comandos;
    }



     public int[] iteracionesDelEnemigoHastaPosicion(Posicion posObj,int maxI){
         //respuesta 0 en que iteracion 1 cuantos
        int[] respuesta=new int[2];
        boolean resuelto=false;
        for(int itAct=0;itAct<maxI;itAct++)
        {

            int aux=0;
            int cuantos=0;
            for(Posicion posAct:spAct.rivales()){
                double distancia=posObj.distancia(posAct);
                double distanciaControl=Constantes.DISTANCIA_CONTROL_BALON;
                if(spAct.detalleJugadoresRivales()[aux].esPortero()){
                     distanciaControl=Constantes.DISTANCIA_CONTROL_BALON_PORTERO;
                }
                double velocidadJugador=spAct.detalleJugadoresRivales()[aux].getVelocidad();
                if(distancia-(distanciaControl+velocidadJugador*itAct)<=0){
                    //llegan
                    cuantos++;
                    resuelto=true;
                    respuesta[0]=itAct;

                }


                aux++;

            }
            if(resuelto){
                    respuesta[1]=cuantos;
                    return respuesta;

                }
         }
        respuesta[0]=-1;
        return respuesta;
    }

     public int simularPase(float fuerza, float angulo,Posicion posAct){
         final int  paseBueno=0;
         final int paseMediano=1;
         final int paseMalo=2;
         return -1;


     }
     public  Simulador.datosTiro calcularPase(Posicion posAct,int jugador,JugadorDetalle jd){
         
         Simulador.datosTiro mejorTiro = null;

         double distActP=posAct.distancia(Constantes.centroArcoSup);
         for (Posicion posPos:spAct.misJugadores()){
            double distPosibleP=posPos.distancia(Constantes.centroArcoSup);
            if(distPosibleP<distActP){
                Simulador.datosTiro tiro=sim.calcularPase(spAct, jd, posAct, posPos);
                if(tiro.tipo==Simulador.PaseBueno||tiro.tipo==Simulador.PaseMediano){

                    mejorTiro=tiro;
                    break;

                }

            }
         }
         return mejorTiro;
         
     }

     public int jugAdelantadoPosible(int j){
         double distAct=spAct.balon().distancia(Constantes.centroArcoSup);
         int jug=-1;
         double distancia=99999;

         double[] distMaxPosible=sim.distanciaHastaControlBalon2(spAct.alturaBalon(),
                     spAct.detalleMisJugadores()[j].getRemate()*1.2+1.2, 45, false);
                     // System.out.println("distancia maxx  "+distMaxPosible[0]+"  fuerza"+(spAct.detalleMisJugadores()[j].getRemate()*1.2+1.2));

         for(int i=0;i<11;i++){
             double distBalon=spAct.balon().distancia(spAct.misJugadores()[i]);
             

             if(distMaxPosible[0]>=distBalon){
                double distPos=spAct.misJugadores()[i].distancia(Constantes.centroArcoSup);
                if(distAct>distPos){
                  distAct=distPos;
                 
                    jug=i;
                }
         }
         }
         return jug;
     }


    
     

}